package com.enterpriseDigitalPlatform.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Value("${spring.data.redis.redisKey}")
    public String redisKey;
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    /**
     * 写入缓存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            operations.set(redisKey + key, OBJECT_MAPPER.writeValueAsString(value));
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 写入缓存设置时间
     *
     * @param key
     * @param value
     * @param expireTime
     * @return
     */
    public boolean setEx(final String key, Object value, long expireTime) {
        boolean result = false;
        try {
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            operations.set(redisKey + key, OBJECT_MAPPER.writeValueAsString(value));
            redisTemplate.expire(redisKey + key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public Object get(final String key) throws JsonProcessingException {
        Object result = null;
        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        result = operations.get(redisKey + key);
        if (result == null) {
            return null;
        }
        result = OBJECT_MAPPER.readValue((String) result, Object.class);
        return result;
    }

    /**
     * 删除对应的value
     *
     * @param key
     */
    public boolean remove(final String key) {
        if (exists(key)) {
            Boolean delete = redisTemplate.delete(redisKey + key);
            return delete;
        }
        return false;

    }

    /**
     * 判断key是否存在
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        boolean result = false;
        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        if (Objects.nonNull(operations.get(redisKey + key))) {
            result = true;
        }
        return result;
    }

    /**
     * 尝试获取锁
     *
     * @param lockKey    锁的键
     * @param requestId  请求标识，用于标识锁的持有者
     * @param expireTime 超时时间（秒）
     * @return 是否获取锁成功
     */
    public boolean tryLock(String lockKey, String requestId, long expireTime) {
        Boolean result = redisTemplate.opsForValue().setIfAbsent(redisKey + lockKey, requestId, expireTime, TimeUnit.SECONDS);
        return Boolean.TRUE.equals(result);
    }

    /**
     * 释放锁
     *
     * @param lockKey   锁的键
     * @param requestId 请求标识，用于验证锁的持有者
     * @return 是否释放锁成功
     */
    public boolean releaseLock(String lockKey, String requestId) {
        String currentValue = (String) redisTemplate.opsForValue().get(redisKey + lockKey);
        if (!ObjectUtils.isEmpty(currentValue) && currentValue.equals(requestId)) {
            return Boolean.TRUE.equals(redisTemplate.delete(lockKey));
        }
        return false;
    }
}
